package com.itheima.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.exception.NcException;
import com.itheima.common.exception.enums.ResponseEnum;
import com.itheima.common.pojo.Constant;
import com.itheima.common.threadlocal.UserHolder;
import com.itheima.common.util.BeanHelper;
import com.itheima.common.util.DateTimeUtil;
import com.itheima.common.vo.PageResult;
import com.itheima.sys.dto.*;
import com.itheima.sys.entity.CompanyUser;
import com.itheima.sys.entity.CompanyUserRole;
import com.itheima.sys.entity.SysRole;
import com.itheima.sys.entity.SysUser;
import com.itheima.sys.mapper.CompanyUserMapper;
import com.itheima.sys.service.ICompanyUserRoleService;
import com.itheima.sys.service.ICompanyUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sys.service.ISysFunctionService;
import com.itheima.sys.service.ISysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 企业与用户关联表 企业-企业与用户关联表 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2020-12-13
 */
@Slf4j
@Service
public class CompanyUserServiceImpl extends ServiceImpl<CompanyUserMapper, CompanyUser> implements ICompanyUserService {


    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private ISysFunctionService sysFunctionService;



    @Override
    public List<CompanyUserDTO> queryCompanyUserById(Long userId, Long companyId) {
        //系统用户ID，企业ID 必须有一个有值
        if (userId == null && companyId == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        QueryWrapper<CompanyUser> queryWrapper = new QueryWrapper<>();
        if(userId!=null){
            queryWrapper.lambda().eq(CompanyUser::getUserId, userId);
        }
        if(companyId!=null){
            queryWrapper.lambda().eq(CompanyUser::getCompanyId, companyId);
        }
        List<CompanyUser> companyUserList = this.list(queryWrapper);
        if(companyUserList.isEmpty()){
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }
        List<CompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(companyUserList, CompanyUserDTO.class);

        //TODO 查询当前系统用户作为员工在每个企业中的 权限信息
        for (CompanyUserDTO companyUserDTO : companyUserDTOList) {
            //设置员工角色
            List<SysRoleDTO> sysRoleDTOList = sysRoleService.queryRoles(companyUserDTO.getId(), companyUserDTO.getCompanyId());
            companyUserDTO.setRoles(sysRoleDTOList);
            //设置员工权限 根据员工ID 查询员工权限
            List<SysFunctionDTO> sysFunctionDTOS = sysFunctionService.queryFunctions(companyUserDTO.getId());
            companyUserDTO.setFunctions(sysFunctionDTOS);
        }
        return companyUserDTOList;
    }



    /**
     * 查询当前企业中所有管理员用户
     * @return
     */
    @Override
    public List<CompanyUserDTO> queryCompanyAdmins() {
        Long companyId = UserHolder.getCompanyId();
        List<CompanyUser> companyUsers = this.getBaseMapper().queryCompanyAdmins(companyId);
        if(companyUsers.isEmpty()){
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        List<CompanyUserDTO> companyUserDTOS = BeanHelper.copyWithCollection(companyUsers, CompanyUserDTO.class);
        //查询当前用户包含角色
        for (CompanyUserDTO companyUserDTO : companyUserDTOS) {
            List<SysRoleDTO> sysRoleDTOList = sysRoleService.queryRoles(companyUserDTO.getId(), companyId);
            companyUserDTO.setRoles(sysRoleDTOList);
        }
        return companyUserDTOS;
    }

    /**
     * 分页查询企业员工列表
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<CompanyUserDTO> queryCompanyMembersByPage(Integer page, Integer pageSize) {
        //查询状态为正常的员工
        QueryWrapper<CompanyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CompanyUser::getEnable, true);
        queryWrapper.lambda().eq(CompanyUser::getCompanyId, UserHolder.getCompanyId());
        //调用mybatisPlus提供分页查询方法
        IPage<CompanyUser> iPage = new Page(page, pageSize);
        iPage = this.page(iPage, queryWrapper);
        List<CompanyUser> companyUsers = iPage.getRecords();
        if(companyUsers.isEmpty()){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }
        List<CompanyUserDTO> companyUserDTOS = BeanHelper.copyWithCollection(companyUsers, CompanyUserDTO.class);
        return new PageResult<>(iPage.getTotal(), iPage.getPages(), companyUserDTOS);
    }

    @Autowired
    private ICompanyUserRoleService companyUserRoleService;

    @Override
    @Transactional
    public void addSubAdmin(CompanyUserAdminDTO companyUserAdminDTO) {
        //1.查询当前用户包含的旧的角色数量
        QueryWrapper<CompanyUserRole> queryWrapper = new QueryWrapper<>();
        Long companyId = UserHolder.getCompanyId();
        queryWrapper.lambda().eq(CompanyUserRole::getCompanyId, companyId);
        queryWrapper.lambda().eq(CompanyUserRole::getCompanyUserId, companyUserAdminDTO.getUserId());
        int count = companyUserRoleService.count(queryWrapper);
        if(count>0){
            //2.如果之前有角色 先删除
            boolean b = companyUserRoleService.remove(queryWrapper);
            if(!b){
                throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
            }
        }

        //3.在新增管理与角色
        List<Long> roleIds = companyUserAdminDTO.getRoleIds();
        if (!roleIds.isEmpty()) {
            ArrayList<CompanyUserRole> companyUserRoles = new ArrayList<>();
            for (Long roleId : roleIds) {
                CompanyUserRole companyUserRole = new CompanyUserRole();
                companyUserRole.setCompanyId(companyId);
                companyUserRole.setRoleId(roleId);
                companyUserRole.setCompanyUserId(companyUserAdminDTO.getUserId());
                companyUserRoles.add(companyUserRole);
            }
            boolean b1 = companyUserRoleService.saveBatch(companyUserRoles);
            if(!b1){
                throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
            }
        }
    }

    @Override
    public CompanyUserDTO getCurrentAdmin(Long companyId) {
        //查询当前企业信息 - 获取到主管理员ID
        if(companyId==null){
            companyId = UserHolder.getCompanyId();
        }
        CompanyUser companyUserAdmin = this.getBaseMapper().getCurrentAdmin(companyId);
        if(companyUserAdmin==null){
            log.error("【系统微服务】-查询当前企业Id：{}，无管理员", companyId);
            throw new NcException(ResponseEnum.COMPANY_ADMIN_NOT_EXISTS);
        }
        return BeanHelper.copyProperties(companyUserAdmin, CompanyUserDTO.class);
    }

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Override
    @Transactional
    public void changeSysAdmin(ChangeMainManagerDTO changeMainManagerDTO) {
        //1.根据提交的员工ID查询员工信息
        Long companyId = UserHolder.getCompanyId();
        QueryWrapper<CompanyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CompanyUser::getCompanyId, companyId);
        queryWrapper.lambda().eq(CompanyUser::getId, changeMainManagerDTO.getUserId());

        CompanyUser newAdminCompanyUser = this.getOne(queryWrapper);
        if (newAdminCompanyUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }


        //2.校验用户提交验证码是否正确
        String code = changeMainManagerDTO.getCode();
        //判断redis中验证码是否存在
        if (!redisTemplate.hasKey(Constant.SMS_CHANGE_MANAGER_KEY_PREFIX + newAdminCompanyUser.getMobile())) {
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }
        //判断用户填写验证码是否正确
        String realCheckcode = redisTemplate.opsForValue().get(Constant.SMS_CHANGE_MANAGER_KEY_PREFIX + newAdminCompanyUser.getMobile());
        if (!realCheckcode.equals(changeMainManagerDTO.getCode())) {
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }
        //2.移除旧管理员员工对应系统管理员角色
        CompanyUserDTO oldSysAdmin = this.getCurrentAdmin(companyId);
        //2.1.2 删除管理员角色
        QueryWrapper<CompanyUserRole> companyUserRoleQueryWrapper = new QueryWrapper<>();
        companyUserRoleQueryWrapper.lambda().eq(CompanyUserRole::getCompanyId, companyId);
        companyUserRoleQueryWrapper.lambda().eq(CompanyUserRole::getCompanyUserId, oldSysAdmin.getId());
        //查询当前企业中 系统管理员角色ID
        SysRole sysAdminRole = sysRoleService.querySysAdminRole(companyId);
        companyUserRoleQueryWrapper.lambda().eq(CompanyUserRole::getRoleId, sysAdminRole.getId());
        Boolean b = companyUserRoleService.remove(companyUserRoleQueryWrapper);
        if(!b){
            throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
        }
        //3.新增新管理员用户对应角色
        CompanyUserRole companyUserRole1 = new CompanyUserRole();
        companyUserRole1.setCompanyId(companyId);
        companyUserRole1.setCompanyUserId(newAdminCompanyUser.getId());
        companyUserRole1.setRoleId(sysAdminRole.getId());
        boolean b2 = companyUserRoleService.save(companyUserRole1);
        if(!b2){
            throw new NcException(ResponseEnum.UPDATE_OPERATION_FAIL);
        }

        //删除验证码
        redisTemplate.delete(Constant.SMS_CHANGE_MANAGER_KEY_PREFIX + newAdminCompanyUser.getMobile());
    }

    /**
     * 根据员工ID
     * @param companyUserId
     * @param companyUserId
     * @return
     */
    @Override
    public CompanyUserDTO queryCompanyUserOne(Long companyUserId) {
        CompanyUser companyUser = this.getById(companyUserId);
        if(companyUser==null){
            throw new NcException(ResponseEnum.COMPANY_USER_NOT_FOUND);
        }
        return BeanHelper.copyProperties(companyUser, CompanyUserDTO.class);
    }

    @Override
    public List<CompanyUserDTO> queryCompanyUserByIds(List<Long> companyUserIds) {
        Collection<CompanyUser> companyUsers = this.listByIds(companyUserIds);
        if(companyUsers.isEmpty()){
            throw new NcException(ResponseEnum.COMPANY_USER_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(companyUsers, CompanyUserDTO.class);
    }

    @Override
    public List<CompanyUserDTO> queryCurrentAllQuery() {
        Long companyId = UserHolder.getCompanyId();
        QueryWrapper<CompanyUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(CompanyUser::getCompanyId, companyId);
        queryWrapper.lambda().eq(CompanyUser::getEnable, false);
        List<CompanyUser> companyUserList = this.list(queryWrapper);
        if(!companyUserList.isEmpty()){
            return BeanHelper.copyWithCollection(companyUserList, CompanyUserDTO.class);
        }
        return null;
    }


}
